diff options
| author | Adam Soltys <[email protected]> | 2024-09-10 20:39:47 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-09-17 09:18:36 -0700 |
| commit | 1f63848ca9fb01336f04b41434de1cc06a5b3d93 (patch) | |
| tree | 2affa3041863be365f33d99e1f32bda60cf93a32 /src/routes/(app)/invoice/[id]/tip | |
| parent | 6e48c584605bec5623c12c470d04d07303983801 (diff) | |
| download | coinos-ui-1f63848ca9fb01336f04b41434de1cc06a5b3d93.tar.gz coinos-ui-1f63848ca9fb01336f04b41434de1cc06a5b3d93.zip | |
move routes
Diffstat (limited to 'src/routes/(app)/invoice/[id]/tip')
| -rw-r--r-- | src/routes/(app)/invoice/[id]/tip/+page.server.ts | 12 | ||||
| -rw-r--r-- | src/routes/(app)/invoice/[id]/tip/+page.svelte | 209 |
2 files changed, 221 insertions, 0 deletions
diff --git a/src/routes/(app)/invoice/[id]/tip/+page.server.ts b/src/routes/(app)/invoice/[id]/tip/+page.server.ts new file mode 100644 index 00000000..8417de91 --- /dev/null +++ b/src/routes/(app)/invoice/[id]/tip/+page.server.ts @@ -0,0 +1,12 @@ +import invoice from "$lib/invoice"; +import { redirect } from "@sveltejs/kit"; + +export async function load({ parent, params }) { + let { invoice } = await parent(); + if (!invoice.amount) + redirect(307, `/invoice/${invoice.id}`); +} + +export const actions = { + default: invoice, +}; diff --git a/src/routes/(app)/invoice/[id]/tip/+page.svelte b/src/routes/(app)/invoice/[id]/tip/+page.svelte new file mode 100644 index 00000000..35b24bf1 --- /dev/null +++ b/src/routes/(app)/invoice/[id]/tip/+page.svelte @@ -0,0 +1,209 @@ +<script> + import { onMount } from "svelte"; + import { browser } from "$app/environment"; + import { invoice as inv, request } from "$lib/store"; + import { copy, focus, f, sat, get, reverseFormat, s, sats } from "$lib/utils"; + import Icon from "$comp/Icon.svelte"; + import Slider from "$comp/Slider.svelte"; + import { goto } from "$app/navigation"; + import { t } from "$lib/translations"; + import { enhance } from "$app/forms"; + import { tick } from "svelte"; + + const tipAmounts = ["No", "10%", "15%", "20%"]; + let showCustomAmount; + + let customInput; + let customTipAmount; + + let apply = async () => { + if (customTipAmount > 0) { + tipPercent = (customTipAmount / amountFiat) * 100; + showCustomAmount = false; + } + }; + + let active = (amount) => + !customTipAmount && Math.round(tipPercent) === parseInt(amount.slice(0, 2)); + + const handleCustomTipAmount = (e) => { + tipPercent = 0; + customTipAmount = e.target.value; + }; + + let timeout; + const handleSlide = (e) => { + customTipAmount = ""; + if (customInput) { + customInput.value = ""; + } + tipPercent = e.target.value; + }; + + let submitting; + const handleTipButtonClick = async (amount) => { + submitting = true; + if (amount === "No") { + tipPercent = 0; + } else { + tipPercent = parseInt(amount.slice(0, 2)); + } + + await tick(); + submit.click(); + }; + + let submit; + + export let data; + $: refresh(data); + let { invoice, id, user, rates } = data; + let { + amount, + hash, + items, + type, + rate, + received, + prompt, + text, + tip, + user: { username, currency }, + } = invoice; + + let qr; + let tipPercent = 0; + + let fullscreen; + + let refresh = (data) => { + $inv = null; + + ({ invoice, id } = data); + ({ + amount, + hash, + items, + type, + received, + prompt, + text, + tip, + user: { username }, + } = invoice); + + tipPercent = (tip / amount) * 100; + }; + + $: currency = user?.currency || invoice.currency; + $: rate = invoice.rate * (rates[currency] / rates[invoice.currency]); + + $: tip = Math.round((amount / 100) * tipPercent); + + $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2)); + + $: tipAmount = ((tip * rate) / sats).toFixed(2); + + $: invoiceAmountFiatFormatted = f(amountFiat, currency); + + onMount(() => ($request = undefined)); +</script> + +<div class="container px-4 max-w-lg text-center mx-auto"> + <form method="POST" use:enhance class:invisible={submitting}> + <input type="hidden" name="amount" value={amount} /> + <input type="hidden" name="tip" value={tip} /> + <input type="hidden" name="username" value={username} /> + <input type="hidden" name="rate" value={invoice.rate} /> + <input type="hidden" name="prompt" value="false" /> + <input type="hidden" name="type" value={type} /> + <input type="hidden" name="hash" value={hash} /> + <input type="hidden" name="items" value={JSON.stringify(items)} /> + + {#if invoice.memoPrompt} + <input type="hidden" name="memoPrompt" value={invoice.memoPrompt} /> + {/if} + + <h1 class="text-4xl font-semibold my-8">{$t("invoice.addTipq")}</h1> + {#if !showCustomAmount} + <div class="my-2 text-xl">{Math.round(tipPercent)}%</div> + + <Slider handle={handleSlide} bind:value={tipPercent} /> + + <div class="flex mb-8 text-lg"> + <div> + <span class="mr-1"> + {f(amountFiat, currency)} + <span class="font-semibold">+{f(tipAmount, currency)}</span> + </span> + </div> + + <div class="ml-auto text-lg"> + {sat(amount)} + <span class="font-semibold">+{sat(tip)}</span> + </div> + </div> + + {#if tip} + <div> + <button type="button" on:click={() => submit.click()}>Next</button> + <button type="button" on:click={() => (tipPercent = 0)}>Reset</button> + </div> + {:else} + {#each tipAmounts as amount} + <button + type="button" + class:active={active(amount, tipPercent)} + on:click={() => handleTipButtonClick(amount)}>{amount}</button + > + {/each} + {/if} + + <div> + <button type="button" on:click={() => (showCustomAmount = true)} + >Custom</button + > + </div> + {/if} + + <button type="submit" bind:this={submit} /> + </form> + + {#if showCustomAmount} + <form on:submit|preventDefault={apply}> + <div class="relative"> + <span + class="absolute top-[18px] left-5 font-semibold {!customTipAmount + ? 'opacity-50' + : 'opacity-100'}">$</span + > + <input + bind:this={customInput} + type="number" + step="0.01" + on:input={(e) => handleCustomTipAmount(e)} + class="pl-10" + placeholder="Custom amount" + use:focus + /> + <button + type="submit" + class="w-full mt-2 bg-black text-white font-semibold py-3 px-7 rounded-2xl {!customTipAmount + ? 'opacity-50' + : 'opacity-100 hover:opacity-80'}" + disabled={!customTipAmount}>Apply</button + > + </div> + </form> + {/if} +</div> + +<style> + .active { + @apply !bg-black !text-white; + } + + .container button[type="button"] { + @apply w-full mt-2 bg-primary text-black hover:bg-black hover:text-white font-semibold py-5 px-7 rounded-2xl; + } +</style> |
